package cn.edu.jxust.core.config;


import cn.edu.jxust.common.domain.entity.Account;
import cn.edu.jxust.common.domain.entity.Role;
import cn.edu.jxust.core.infrastructure.util.authc.JwtToken;
import cn.edu.jxust.core.domain.repository.AccountService;
import cn.edu.jxust.core.domain.repository.ResourceService;
import cn.edu.jxust.core.domain.repository.RoleResourceService;
import cn.edu.jxust.core.domain.repository.RoleService;
import cn.edu.jxust.core.infrastructure.util.authc.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;

/**
 * @author QiuKangming
 * @version 1.0
 * @description 账户授权数据桥梁
 * @since 2020/06/18 13:35
 */

@Slf4j
public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    private AccountService accountService;
    @Autowired
    private RoleResourceService roleResourceService;
    @Autowired
    private ResourceService resourceService;
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private RoleService roleService;


    /**
     * 指定自己定义的realm
     * @param token 访问令牌
     * @return boolean
     */
    @Override
    public boolean supports(AuthenticationToken token) {

        return token instanceof JwtToken;

    }

    /**
     * 授权逻辑方法
     * @param principalCollection principalCollection
     * @return AuthorizationInfo
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        if(principalCollection.getPrimaryPrincipal() != null){
            //获取的是 Account 对象
            Account account = (Account) principalCollection.getPrimaryPrincipal();
            //获取账户名
            //给账户进行授权
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            //设置角色
            Role role = roleService.getRole(account.getRoleId());
            info.addRole(role.getRoleName());
            //根据角色获取相应的权限 ids
            List<Integer> ids = roleResourceService.getResourceIdsByRoleId(account.getRoleId());
            if(ids == null || ids.size() == 0){
                log.warn("[doGetAuthorizationInfo]: 当前用户无任何权限!");
                return info;
            }
            //设置权限
            List<String> permissions = resourceService.getPermissionListByIds(ids);
            //添加授权字符串
            info.addStringPermissions(permissions);
            return info;
        }
        return null;
    }

    /**
     * 认证逻辑方法
     * @param token 访问令牌
     * @return AuthenticationInfo
     * @throws AuthenticationException e
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        //token 是 JwtToken 类型
        JwtToken jwtToken = (JwtToken) token;
        //解密获得 accountName
        String accountName = jwtUtils.getAccountName(jwtToken.getCredentials().toString());
        Account account = accountService.getByAccName(accountName);
        return new SimpleAuthenticationInfo(account, jwtToken.getCredentials(), null,"shiroRealm");

    }

}
